package tencentcloud

import (
	"fmt"
	appv1 "gitee.com/amoyx/devops-infras/api/v1"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
	redis "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/redis/v20180412"
	"strconv"
	"strings"
)

type RedisCloud interface {
	CreateRedis(*appv1.Redis) (redis.CreateInstancesResponseParams, error)
	DescribeRedis(string) (redis.DescribeInstancesResponseParams, error)
	RedisWanAddress(string, bool) error
	ResetRedisPassword(string, string) bool
	QueryRedisTaskInfo(uint64) (*redis.DescribeTaskInfoResponseParams, error)
	DestroyRedis(string, bool) (string, error)
	QueryRedisTaskListInfo(string) (*redis.DescribeTaskListResponseParams, error)
	QueryRedisOrderInfo([]string) (*redis.DescribeInstanceDealDetailResponseParams, error)
	RedisRecover(string) (*int64, error)
}

func (r *RealTencentCloud) CreateRedis(in *appv1.Redis) (redis.CreateInstancesResponseParams, error) {
	request := redis.NewCreateInstancesRequest()
	request.ZoneId = common.Uint64Ptr(in.Spec.ZoneId)
	request.TypeId = common.Uint64Ptr(in.Spec.TypeId)
	request.MemSize = common.Uint64Ptr(in.Spec.MemSize)
	request.GoodsNum = common.Uint64Ptr(in.Spec.GoodsNum)
	request.Period = common.Uint64Ptr(in.Spec.Period)
	request.Password = common.StringPtr(in.Spec.Password)
	request.VpcId = common.StringPtr(in.Spec.VpcId)
	request.SubnetId = common.StringPtr(in.Spec.SubnetId)
	request.AutoRenew = common.Uint64Ptr(1)
	request.VPort = common.Uint64Ptr(in.Spec.VPort)
	request.BillingMode = common.Int64Ptr(in.Spec.BillingMode)
	request.InstanceName = common.StringPtr(in.Spec.InstanceName)
	if sg, err := r.DefaultSecurityGroup(); err == nil {
		request.SecurityGroupIdList = common.StringPtrs([]string{sg})
	}
	response, err := r.redisClient.CreateInstances(request)
	return *response.Response, err
}

// DescribeRedis 获取redis实例
func (r *RealTencentCloud) DescribeRedis(id string) (redis.DescribeInstancesResponseParams, error) {
	request := redis.NewDescribeInstancesRequest()
	request.InstanceId = common.StringPtr(id)
	response, err := r.redisClient.DescribeInstances(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Printf("获取redis实例错误: %s", err)
		return redis.DescribeInstancesResponseParams{}, err
	}
	return *response.Response, nil
}

// RedisWanAddress 开启或关闭redis公网地址
func (r *RealTencentCloud) RedisWanAddress(id string, enable bool) error {
	if enable {
		request := redis.NewAllocateWanAddressRequest()
		request.InstanceId = common.StringPtr(id)
		_, err := r.redisClient.AllocateWanAddress(request)
		return err
	} else {
		request := redis.NewReleaseWanAddressRequest()
		request.InstanceId = common.StringPtr(id)
		_, err := r.redisClient.ReleaseWanAddress(request)
		return err
	}
}

// ResetRedisPassword 重置Redis密码
func (r *RealTencentCloud) ResetRedisPassword(id string, passwd string) bool {
	request := redis.NewResetPasswordRequest()
	request.InstanceId = common.StringPtr(id)
	request.Password = common.StringPtr(passwd)
	_, err := r.redisClient.ResetPassword(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Println("Redis密码更新错误！", err)
		return false
	}
	return true
}

// QueryRedisTaskInfo 查询redis实例任务信息
func (r *RealTencentCloud) QueryRedisTaskInfo(taskId uint64) (*redis.DescribeTaskInfoResponseParams, error) {
	request := redis.NewDescribeTaskInfoRequest()
	request.TaskId = common.Uint64Ptr(taskId)
	response, err := r.redisClient.DescribeTaskInfo(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Printf("获取redis任务信息失败: %s", err)
		return nil, err
	}
	return response.Response, nil
}

// DestroyRedis 销毁redis实例
func (r *RealTencentCloud) DestroyRedis(id string, isPrepaid bool) (string, error) {
	if isPrepaid {
		request := redis.NewDestroyPrepaidInstanceRequest()
		request.InstanceId = common.StringPtr(id)
		response, err := r.redisClient.DestroyPrepaidInstance(request)
		if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
			fmt.Printf("销毁redis实例错误: %s", err)
			return "", err
		}
		return *response.Response.DealId, nil
	} else {
		request := redis.NewDestroyPostpaidInstanceRequest()
		request.InstanceId = common.StringPtr(id)
		response, err := r.redisClient.DestroyPostpaidInstance(request)
		if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
			fmt.Printf("销毁redis实例错误: %s", err)
			return "", err
		}
		return strconv.FormatInt(*response.Response.TaskId, 10), nil
	}
}

// QueryRedisTaskListInfo 查询redis任务列表信息
func (r *RealTencentCloud) QueryRedisTaskListInfo(id string) (*redis.DescribeTaskListResponseParams, error) {
	request := redis.NewDescribeTaskListRequest()
	if strings.TrimSpace(id) != "" {
		request.InstanceId = common.StringPtr(id)
	}
	response, err := r.redisClient.DescribeTaskList(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Printf("获取redis任务列表错误: %s", err)
		return nil, err
	}
	return response.Response, nil
}

// QueryRedisOrderInfo 查询redis订单信息
func (r *RealTencentCloud) QueryRedisOrderInfo(orderId []string) (*redis.DescribeInstanceDealDetailResponseParams, error) {
	request := redis.NewDescribeInstanceDealDetailRequest()
	request.DealIds = common.StringPtrs(orderId)
	response, err := r.redisClient.DescribeInstanceDealDetail(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Printf("获取Redis订单信息错误: %s", err)
		return nil, err
	}
	return response.Response, nil
}

// RedisRecover redis实例回收
func (r *RealTencentCloud) RedisRecover(id string) (*int64, error) {
	request := redis.NewCleanUpInstanceRequest()
	request.InstanceId = common.StringPtr(id)
	response, err := r.redisClient.CleanUpInstance(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok || err != nil {
		fmt.Printf("redis实例回收报错: %s", err)
		return nil, err
	}
	return response.Response.TaskId, nil
}
